﻿using System;
using System.Text;
using System.Collections.Generic;

namespace Model
{
    public class Verse
    {
        public const int MIN_NUMBER = 1;
        public const int MAX_NUMBER = 6236;

        private Book book = null;
        public Book Book
        {
            get { return book; }
            set { book = value; }
        }

        private Chapter chapter = null;
        public Chapter Chapter
        {
            get { return chapter; }
            set { chapter = value; }
        }

        private int number;
        public int Number
        {
            get { return number; }
            set { number = value; }
        }

        private int number_in_chapter = 0;
        public int NumberInChapter
        {
            set { number_in_chapter = value; }
            get
            {
                if (number_in_chapter == 0)
                {
                    if (this.book != null)
                    {
                        if (this.book.Chapters != null)
                        {
                            number_in_chapter = number;
                            foreach (Chapter chapter in this.book.Chapters)
                            {
                                if (chapter == this.chapter)
                                {
                                    break;
                                }
                                number_in_chapter -= chapter.Verses.Count;
                            }
                        }
                    }
                }
                return number_in_chapter;
            }
        }

        public string Address
        {
            get
            {
                if (chapter != null)
                {
                    return (this.chapter.Number.ToString() + ":" + NumberInChapter.ToString());
                }
                return "0:0";
            }
        }
        public string PaddedAddress
        {
            get
            {
                if (chapter != null)
                {
                    return (this.chapter.Number.ToString("000") + ":" + NumberInChapter.ToString("000"));
                }
                return "000:000";
            }
        }
        public string ArabicAddress
        {
            get
            {
                if (chapter != null)
                {
                    return (this.chapter.Number.ToArabic() + "_" + NumberInChapter.ToArabic());
                }
                return "٠:٠";
            }
        }

        private Station station = null;
        public Station Station
        {
            get { return station; }
            set { station = value; }
        }

        private Part part = null;
        public Part Part
        {
            get { return part; }
            set { part = value; }
        }

        private Group group = null;
        public Group Group
        {
            get { return group; }
            set { group = value; }
        }

        private Quarter quarter = null;
        public Quarter Quarter
        {
            get { return quarter; }
            set { quarter = value; }
        }

        private Bowing bowing = null;
        public Bowing Bowing
        {
            get { return bowing; }
            set { bowing = value; }
        }

        private Page page = null;
        public Page Page
        {
            get { return page; }
            set { page = value; }
        }

        private Prostration prostration = null;
        public Prostration Prostration
        {
            get { return prostration; }
            set { prostration = value; }
        }

        private List<Word> words = null;
        public List<Word> Words
        {
            get { return words; }
        }

        public const string OPEN_BRACKET = "{";
        public const string CLOSE_BRACKET = "}";
        public string Endmark
        {
            get
            {
                if (s_include_number)
                {
                    return " " + OPEN_BRACKET + NumberInChapter.ToString().ToArabicNumber() + CLOSE_BRACKET + " ";
                }
                else
                {
                    return "\r\n";
                }
            }
        }

        private static bool s_include_number;
        public static bool IncludeNumber
        {
            get { return s_include_number; }
            set { s_include_number = value; }
        }
        
        /// <summary>
        /// Create a verse with the Original text, use SetText method to add simplified texts later.
        /// </summary>
        /// <param name="number"></param>
        /// <param name="text"></param>
        public Verse(int number, string text)
        {
            this.number = number;
            if (!String.IsNullOrEmpty(text))
            {
                text = text.Replace("\r", "");
                text = text.Replace("\n", "");
                this.text = text;

                BuildWordsAndLetters(this.text);
            }
        }
        private void BuildWordsAndLetters(string text)
        {
            if (!String.IsNullOrEmpty(text))
            {
                if (this.words == null)
                {
                    this.words = new List<Word>();
                }
                else
                {
                    this.words.Clear();
                }

                int word_number_in_verse = 0;
                int word_position_in_verse = 0;
                string[] word_texts = text.Split(' ');
                foreach (string word_text in word_texts)
                {
                    // skip stop marks (1-letter words), except real Quranic 1-letter words
                    if ((word_text.Length == 1) && (word_text != "ص") && (word_text != "ق") && (word_text != "ن"))
                    {
                        word_position_in_verse += 2; // stop mark and space after it
                        continue; // skip stop mark
                    }
                    else
                    {
                        word_number_in_verse++;
                        Word word = new Word(this, word_number_in_verse, word_position_in_verse, word_text);
                        this.words.Add(word);
                    }

                    // in all cases
                    word_position_in_verse += word_text.Length + 1; // 1 for space
                }
            }
        }

        private string text;
        public string Text
        {
            get { return text; }
            set
            {
                this.text = value;
                BuildWordsAndLetters(this.text);
            }
        }

        public Dictionary<string, string> Translations = new Dictionary<string, string>();
    }
}
